using System;
using System.Diagnostics;

namespace Utils
{
    public sealed class Check
    {
        #region Interface
        /// <summary>
        /// Set this if you wish to use Trace Assert statements 
        /// instead of exception handling. 
        /// (The Check class uses exception handling by default.)
        /// </summary>
        public static bool UseAssertions
        {
            get { return useAssertions; }
            set { useAssertions = value; }
        }
        public static void Assert(bool assertion)
        {
            Assert(assertion,"Unspecified Error");
        }
        /// <summary>
        /// Assertion check.
        /// </summary>
        public static void Assert(bool assertion, string message)
        {
            if (UseExceptions)
            {
                if (!assertion)
                {
                    AssertionException _assertionException = new AssertionException(message);
                    Logger.Instance.LogException(_assertionException);
                    throw _assertionException;
                }
            }
            else
            {
                Trace.Assert(assertion, "Assertion: " + message);
            }
        }
        #endregion // Interface

        #region Implementation
        // No creation
        private static bool useAssertions = false;
        private Check()
        {
        }
        /// <summary>
        /// Is exception handling being used?
        /// </summary>
        private static bool UseExceptions
        {
            get { return !useAssertions; }
        }
        // Are trace assertion statements being used? 
        // Default is to use exception handling.
        #endregion // Implementation
    } // End Check

    #region Exceptions
    /// <summary>
    /// Exception raised when a contract is broken.
    /// Catch this exception type if you wish to differentiate between 
    /// any DesignByContract exception and other runtime exceptions.
    ///  
    /// </summary>
    public class DesignByContractException : ApplicationException
    {
        protected DesignByContractException()
        {
        }
        protected DesignByContractException(string message) : base(message)
        {
        }
        protected DesignByContractException(string message, Exception inner) : base(message, inner)
        {
        }
    }
    /// <summary>
    /// Exception raised when an assertion fails.
    /// </summary>
    public class AssertionException : DesignByContractException
    {
        /// <summary>
        /// Assertion Exception.
        /// </summary>
        public AssertionException()
        {
        }
        /// <summary>
        /// Assertion Exception.
        /// </summary>
        public AssertionException(string message) : base(message)
        {
        }
        /// <summary>
        /// Assertion Exception.
        /// </summary>
        public AssertionException(string message, Exception inner) : base(message, inner)
        {
        }
    }
    #endregion // Exception classes
}